-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Code Quality: Improved WindowsStorables #17191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
671e280
to
a9ef2a8
Compare
public IShellItem* ThisPtr | ||
{ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
get; | ||
|
||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
protected set; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dongle-the-gadget Could you review for real quick? I unwrapped the ptr-s where they are passed to constructors of WindowsFile or WindowsFolder, which means they shouldnt be disposed outside the block where defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just wanna make sure pointer managements around windows storables are done appropriately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have some code where the storables are used? In general you shouldn't call Release on the pointers you pass to the constructor as it looks like those objects take ownership.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've ensured all of the instantiation is done witout releasing.
// Instead of:
ComPtr<IShellItem> pShellItem = ...;
var folder = new WindowsFolder(pShellItem.Get());
// Did this. because no reason to use ComPtr.
IShellItem* pShellItem = ...;
var folder = new WindowsFolder(pShellItem);
public static WindowsStorable? TryParse(string szPath) | |
{ | |
HRESULT hr = default; | |
IShellItem* pShellItem = null; | |
fixed (char* pszPath = szPath) | |
hr = PInvoke.SHCreateItemFromParsingName(pszPath, null, IID.IID_IShellItem, (void**)&pShellItem); | |
if (pShellItem is null) | |
return null; | |
return TryParse(pShellItem); | |
} | |
public static WindowsStorable? TryParse(IShellItem* pShellItem) | |
{ | |
bool isFolder = pShellItem->GetAttributes(SFGAO_FLAGS.SFGAO_FOLDER, out var returnedAttributes).Succeeded && returnedAttributes == SFGAO_FLAGS.SFGAO_FOLDER; | |
return isFolder ? new WindowsFolder(pShellItem) : new WindowsFile(pShellItem); | |
} |
Files/src/Files.App/ViewModels/UserControls/Widgets/QuickAccessWidgetViewModel.cs
Lines 235 to 253 in acac1a3
unsafe | |
{ | |
hr = PInvoke.RoGetAgileReference(AgileReferenceOptions.AGILEREFERENCE_DEFAULT, IID.IID_IShellItem, (IUnknown*)folderCardItem.Item.ThisPtr, pAgileReference.GetAddressOf()); | |
} | |
// Unpin from Quick Access on Windows | |
hr = await STATask.Run(() => | |
{ | |
unsafe | |
{ | |
IShellItem* pShellItem = null; | |
hr = pAgileReference.Get()->Resolve(IID.IID_IShellItem, (void**)&pShellItem); | |
using var windowsFile = new WindowsFile(pShellItem); | |
// NOTE: "unpinfromhome" is an undocumented verb, which calls an undocumented COM class, windows.storage.dll!CRemoveFromFrequentPlacesExecute : public IExecuteCommand, ... | |
// NOTE: "remove" is for some shell folders where the "unpinfromhome" may not work | |
return windowsFile.TryInvokeContextMenuVerbs(["unpinfromhome", "remove"], true); | |
} | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is everything then disposed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is everything then disposed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes as of now.
But I'm very very concerned, this project is community driven; if someone uses these classes wrongly, the app immediately starts leaking memory/crashing out, etc. Being so, I probably am going to introduce a new analyzer to warn them at the instantiations that are done without using
(if using
should not be used at that point, they can suppress) but not clear how much that can help.
var folder = new WindowsFolder(pShellItem.Get());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This class much be disposed of, consider to add 'using'.
Worth having it stand out:
#pragma disable warning FSG1xxx // ...
var folder = new WindowsFolder(pShellItem.Get());
#pragma enable warning FGS1xxx // ...
|
Resolved / Related Issues
Steps used to test these changes